package model

import (
	"errors"
	"time"

	"gorm.io/gorm"
)

// BaseModel 基础模型
type BaseModel struct {
}

func (b *BaseModel) TableName() string {
	return "base_model"
}

// 通用查询条件封装
type QueryOptions struct {
	SelectedFields []string
	Conditions     map[string]interface{}
	OrConditions   map[string]interface{}
	OrderBy        string
	GroupBy        string
	Offset         int  // 跳过条数
	Page           int  // 页码
	PageSize       int  // 每页条数
	Debug          bool //打印日志
}

// 多条数据查询
func GetModelData(db *gorm.DB, tableName string, modelSlice interface{}, options QueryOptions) error {
	result := db.Table(tableName)

	if options.Debug {
		result = result.Debug()
	}

	// 选择查询的字段
	if len(options.SelectedFields) > 0 {
		result = result.Select(options.SelectedFields)
	}

	//where查询
	for field, value := range options.Conditions {
		result = result.Where(field, value)
	}

	// 添加 OR 条件
	if len(options.OrConditions) > 0 {
		result = result.Or(options.OrConditions)
	}

	// 分组
	if options.GroupBy != "" {
		result = result.Group(options.GroupBy)
	}

	// 排序
	if options.OrderBy != "" {
		result = result.Order(options.OrderBy)
	}

	// 分页
	if options.Page > 0 && options.PageSize > 0 {
		offset := (options.Page - 1) * options.PageSize
		result = result.Offset(offset).Limit(options.PageSize)
	}

	if options.Offset > 0 {
		result = result.Offset(options.Offset)
	}

	return result.Find(modelSlice).Error
}

// 单条数据查询
func GetModelDataFirst(db *gorm.DB, tableName string, model interface{}, options QueryOptions) (bool, error) {
	result := db.Table(tableName)
	// 选择查询的字段
	if len(options.SelectedFields) > 0 {
		result = result.Select(options.SelectedFields)
	}

	// where查询
	for field, value := range options.Conditions {
		result = result.Where(field, value)
	}

	// 添加 OR 条件
	if len(options.OrConditions) > 0 {
		result = result.Or(options.OrConditions)
	}

	// 排序
	if options.OrderBy != "" {
		result = result.Order(options.OrderBy)
	}

	// 查询第一条记录
	err := result.First(model).Error

	// 判断记录是否存在
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return false, nil
	} else if err != nil {
		return false, err
	}

	return true, nil
}

// 查询总数
func CountModelData(db *gorm.DB, tableName string, options QueryOptions) (int, error) {
	var count int64

	result := db.Table(tableName)

	if options.Debug {
		result = result.Debug()
	}

	// where 查询
	for field, value := range options.Conditions {
		result = result.Where(field, value)
	}

	// 添加 OR 条件
	if len(options.OrConditions) > 0 {
		result = result.Or(options.OrConditions)
	}

	// 分组
	if options.GroupBy != "" {
		result = result.Group(options.GroupBy)
	}

	err := result.Count(&count).Error

	return int(count), err
}

// 新增数据
func CreateModelData(db *gorm.DB, tableName string, model map[string]interface{}) error {
	model["created_at"] = time.Now()
	model["updated_at"] = time.Now()
	return db.Debug().Table(tableName).Create(model).Error
}

// 修改数据
func UpdateModelData(db *gorm.DB, tableName string, conditions map[string]interface{}, model map[string]interface{}) error {
	model["updated_at"] = time.Now()
	return db.Debug().Table(tableName).Where(conditions).Updates(model).Error
}

// 删除数据
func DeleteModelData(db *gorm.DB, tableName string, conditions map[string]interface{}, model interface{}) error {
	return db.Table(tableName).Debug().Where(conditions).Delete(model).Error
}

// 判断是否为未找到记录的错误
func IsNotFoundError(err error) bool {
	return errors.Is(err, gorm.ErrRecordNotFound)
}

// 判断字符串是否在切片中
func IsStringInSlice(target string, slice []string) bool {
	for _, item := range slice {
		if item == target {
			return true
		}
	}
	return false
}
